import { Wallet as SolanaWalletAdapter } from '@solana/wallet-adapter-react'
import { WalletName, WalletReadyState } from '@solana/wallet-adapter-base'
import safeGetWindow from '@pancakeswap/utils/safeGetWindow'
import { ChainId } from '@pancakeswap/chains'
import { WalletAdaptedNetwork, WalletConfigV3 } from '../types'
import { WalletIds } from './walletIds'
import { EvmConnectorNames, SolanaWalletNames, SolanaConnectorNames } from './connectorNames'
import {
  isBinanceWeb3WalletInstalled,
  isBraveWalletInstalled,
  isCoin98Installed,
  isMathWalletInstalled,
  isMetamaskInstalled,
  isOkxWalletInstalled,
  isOperaWalletInstalled,
  isRabbyWalletInstalled,
  isSafePalInstalled,
  isTokenPocketInstalled,
  isTrustWalletInstalled,
} from './installed'
import { ASSET_CDN } from './url'
import { WalletFilterValue } from '../state/hooks'

// Wrapper that keeps getter but makes it safe
export function wrapInstalledSafe<T extends { id: any; installed?: boolean }>(walletConfig: T): T {
  if (!walletConfig) return walletConfig
  const descriptor = Object.getOwnPropertyDescriptor(walletConfig, 'installed')

  if (descriptor && typeof descriptor.get === 'function') {
    const originalInstalledGetter = descriptor.get

    Object.defineProperty(walletConfig, 'installed', {
      get() {
        try {
          return originalInstalledGetter.call(this)
        } catch (error) {
          console.error(`Error in installed getter for wallet ${walletConfig.id || 'unknown'}:`, error)
          return false
        }
      },
      configurable: descriptor.configurable,
      enumerable: descriptor.enumerable,
    })
  }

  return walletConfig
}

function getBinanceConnectorId() {
  const globalWindow = safeGetWindow()

  if (!globalWindow) return EvmConnectorNames.BinanceW3W

  // use Binance App
  if (globalWindow.isBinance) return EvmConnectorNames.Injected

  // use Binance Web3 Wallet Extension
  if (globalWindow.binancew3w) return EvmConnectorNames.BinanceW3W

  return EvmConnectorNames.BinanceW3W
}

export const getWalletsConfig = ({
  walletFilter,
  createEvmQrCode,
  solanaWalletAdapters,
}: {
  walletFilter: WalletFilterValue
  createEvmQrCode?: () => () => Promise<string>
  solanaWalletAdapters: SolanaWalletAdapter[]
}): WalletConfigV3[] => {
  const qrCode = createEvmQrCode ? createEvmQrCode() : undefined
  const isSolanaWalletInstalled = (walletName: WalletName) => {
    if (!solanaWalletAdapters || solanaWalletAdapters.length === 0) return false
    return solanaWalletAdapters.some(
      (wallet) => wallet.adapter.name === walletName && wallet.readyState === WalletReadyState.Installed,
    )
  }
  const wallets = [
    {
      id: WalletIds.Metamask,
      title: 'Metamask',
      icon: `${ASSET_CDN}/web/wallets/metamask.png`,
      networks: [WalletAdaptedNetwork.EVM, WalletAdaptedNetwork.Solana],
      get installed() {
        return isMetamaskInstalled()
      },
      connectorId: EvmConnectorNames.Injected,
      solanaAdapterName: SolanaWalletNames.MetaMask,
      deepLink: 'https://metamask.app.link/dapp/pancakeswap.finance/',
      qrCode,
      downloadLink: 'https://metamask.app.link/dapp/pancakeswap.finance/',
      MEVSupported: true,
    },
    {
      id: WalletIds.Trust,
      title: 'Trust Wallet',
      icon: `${ASSET_CDN}/web/wallets/trust.png`,
      connectorId: EvmConnectorNames.Injected,
      solanaAdapterName: SolanaWalletNames.Trust,
      networks: [WalletAdaptedNetwork.EVM, WalletAdaptedNetwork.Solana],
      get installed() {
        return isTrustWalletInstalled()
      },
      deepLink: 'https://link.trustwallet.com/open_url?coin_id=20000714&url=https://pancakeswap.finance/',
      downloadLink: 'https://trustwallet.com/browser-extension',
      guide: {
        desktop: 'https://trustwallet.com/browser-extension',
        mobile: 'https://trustwallet.com/',
      },
      qrCode,
      MEVSupported: true,
    },
    {
      id: WalletIds.Okx,
      title: 'OKX Wallet',
      icon: `${ASSET_CDN}/web/wallets/okx-wallet.png`,
      connectorId: EvmConnectorNames.Injected,
      solanaAdapterName: SolanaWalletNames.Okx,
      networks: [WalletAdaptedNetwork.EVM, WalletAdaptedNetwork.Solana],
      get installed() {
        return isOkxWalletInstalled()
      },
      downloadLink: 'https://www.okx.com/download',
      deepLink:
        'https://www.okx.com/download?deeplink=okx%3A%2F%2Fwallet%2Fdapp%2Furl%3FdappUrl%3Dhttps%253A%252F%252Fpancakeswap.finance',
      guide: {
        desktop: 'https://www.okx.com/web3',
        mobile: 'https://www.okx.com/web3',
      },
      qrCode,
    },
    {
      id: WalletIds.BinanceW3W,
      title: 'Binance Wallet',
      icon: `${ASSET_CDN}/web/wallets/binance-w3w.png`,
      connectorId: EvmConnectorNames.BinanceW3W,
      solanaAdapterName: SolanaWalletNames.BinanceW3W,
      networks: [WalletAdaptedNetwork.EVM, WalletAdaptedNetwork.Solana],
      get installed() {
        return isBinanceWeb3WalletInstalled()
      },
      evmCanInitWithoutInstall: true,
      solanaCanInitWithoutInstall: false,
      MEVSupported: true,
    },
    {
      id: WalletIds.Coinbase,
      title: 'Coinbase Wallet',
      icon: `${ASSET_CDN}/web/wallets/coinbase.png`,
      connectorId: EvmConnectorNames.WalletLink,
      solanaAdapterName: SolanaWalletNames.Coinbase,
      networks: [WalletAdaptedNetwork.EVM, WalletAdaptedNetwork.Solana],
      get installed() {
        return isSolanaWalletInstalled(SolanaWalletNames.Coinbase)
      },
      evmCanInitWithoutInstall: true,
      solanaCanInitWithoutInstall: false,
      downloadLink: 'https://www.coinbase.com/wallet/downloads',
    },
    {
      id: WalletIds.Walletconnect,
      title: 'WalletConnect',
      icon: `${ASSET_CDN}/web/wallets/walletconnect.png`,
      connectorId: EvmConnectorNames.WalletConnect,
      // solanaAdapterName: SolanaWalletNames.WalletConnect,
      // networks: [WalletAdaptedNetwork.EVM, WalletAdaptedNetwork.Solana],
      networks: [WalletAdaptedNetwork.EVM],
      // solanaCanInitWithoutInstall: true,
      evmCanInitWithoutInstall: true,
    },
    {
      id: WalletIds.Opera,
      title: 'Opera Wallet',
      icon: `${ASSET_CDN}/web/wallets/opera.png`,
      connectorId: EvmConnectorNames.Injected,
      networks: [WalletAdaptedNetwork.EVM],
      get installed() {
        return isOperaWalletInstalled()
      },
      downloadLink: 'https://www.opera.com/crypto/next',
    },
    {
      id: WalletIds.Brave,
      title: 'Brave Wallet',
      icon: `${ASSET_CDN}/web/wallets/brave.png`,
      connectorId: EvmConnectorNames.Injected,
      networks: [WalletAdaptedNetwork.EVM],
      get installed() {
        return isBraveWalletInstalled()
      },
      downloadLink: 'https://brave.com/wallet/',
    },
    {
      id: WalletIds.Rabby,
      title: 'Rabby Wallet',
      icon: `${ASSET_CDN}/web/wallets/rabby.png`,
      connectorId: EvmConnectorNames.Injected,
      networks: [WalletAdaptedNetwork.EVM],
      get installed() {
        return isRabbyWalletInstalled()
      },
      guide: {
        desktop: 'https://rabby.io/',
      },
      downloadLink: {
        desktop: 'https://rabby.io/',
      },
      qrCode,
      MEVSupported: true,
    },
    {
      id: WalletIds.Math,
      title: 'MathWallet',
      icon: `${ASSET_CDN}/web/wallets/mathwallet.png`,
      connectorId: EvmConnectorNames.Injected,
      networks: [WalletAdaptedNetwork.EVM],
      get installed() {
        return isMathWalletInstalled()
      },
      qrCode,
    },
    {
      id: WalletIds.Tokenpocket,
      title: 'TokenPocket',
      icon: `${ASSET_CDN}/web/wallets/tokenpocket.png`,
      connectorId: EvmConnectorNames.Injected,
      solanaAdapterName: SolanaWalletNames.TokenPocket,
      networks: [WalletAdaptedNetwork.EVM, WalletAdaptedNetwork.Solana],
      get installed() {
        return isTokenPocketInstalled()
      },
      qrCode,
      downloadLink: 'https://tokenpocket.pro',
    },
    {
      id: WalletIds.SafePal,
      title: 'SafePal',
      icon: `${ASSET_CDN}/web/wallets/safepal.png`,
      connectorId: EvmConnectorNames.Injected,
      solanaAdapterName: SolanaWalletNames.SafePal,
      networks: [WalletAdaptedNetwork.EVM, WalletAdaptedNetwork.Solana],
      get installed() {
        return isSafePalInstalled()
      },
      downloadLink: 'https://safepal.com/en/extension',
      qrCode,
    },
    {
      id: WalletIds.Coin98,
      title: 'Coin98',
      icon: `${ASSET_CDN}/web/wallets/coin98.png`,
      connectorId: EvmConnectorNames.Injected,
      solanaAdapterName: SolanaWalletNames.Coin98,
      networks: [WalletAdaptedNetwork.EVM, WalletAdaptedNetwork.Solana],
      get installed() {
        return isCoin98Installed()
      },
      qrCode,
    },
    // {
    //   id: WalletIds.Cyberwallet,
    //   title: 'CyberWallet',
    //   icon: `${ASSET_CDN}/web/wallets/cyberwallet.png`,
    //   connectorId: EvmConnectorNames.Injected,
    //   networks: [WalletAdaptedNetwork.EVM],
    //   get installed() {
    //     return isCyberWalletInstalled()
    //   },
    //   isNotExtension: true,
    // },

    {
      id: WalletIds.Phantom,
      title: 'Phantom',
      icon: '',
      connectorId: SolanaWalletNames.Phantom,
      solanaAdapterName: SolanaWalletNames.Phantom,
      networks: [WalletAdaptedNetwork.Solana],
      get installed() {
        return isSolanaWalletInstalled(SolanaWalletNames.Phantom)
      },
      downloadLink: 'https://phantom.com/',
    },

    {
      id: WalletIds.Solflare,
      title: 'Solflare',
      icon: '',
      connectorId: SolanaWalletNames.Solflare,
      solanaAdapterName: SolanaWalletNames.Solflare,
      networks: [WalletAdaptedNetwork.Solana],
      get installed() {
        return isSolanaWalletInstalled(SolanaWalletNames.Solflare) || Boolean((safeGetWindow() as any)?.solflare)
      },
      downloadLink: 'https://solflare.com',
    },

    // {
    //   id: WalletIds.Slope,
    //   title: 'Slope',
    //   icon: '',
    //   connectorId: SolanaWalletNames.Slope,
    //   solanaAdapterName: SolanaWalletNames.Slope,
    //   networks: [WalletAdaptedNetwork.Solana],
    //   get installed() {
    //     return isSolanaWalletInstalled(SolanaWalletNames.Slope)
    //   },
    //   downloadLink: 'https://slope.finance/',
    // },
    {
      id: WalletIds.Glow,
      title: 'Glow',
      icon: '',
      connectorId: SolanaWalletNames.Glow,
      solanaAdapterName: SolanaWalletNames.Glow,
      networks: [WalletAdaptedNetwork.Solana],
      get installed() {
        return isSolanaWalletInstalled(SolanaWalletNames.Glow)
      },
      downloadLink: 'https://glow.app',
    },
    {
      id: WalletIds.BitGet,
      title: 'BitGet',
      icon: '',
      connectorId: SolanaWalletNames.Bitget,
      solanaAdapterName: SolanaWalletNames.Bitget,
      networks: [WalletAdaptedNetwork.Solana],
      get installed() {
        return isSolanaWalletInstalled(SolanaWalletNames.Bitget)
      },
      downloadLink: 'https://web3.bitget.com',
    },
    {
      id: WalletIds.Exodus,
      title: 'Exodus',
      icon: '',
      connectorId: SolanaWalletNames.Exodus,
      solanaAdapterName: SolanaWalletNames.Exodus,
      networks: [WalletAdaptedNetwork.Solana],
      get installed() {
        return isSolanaWalletInstalled(SolanaWalletNames.Exodus)
      },
      downloadLink: 'https://www.exodus.com/browser-extension',
    },
    {
      id: WalletIds.Backpack,
      title: 'Backpack',
      icon: 'https://backpack.app/favicon.ico',
      connectorId: SolanaWalletNames.Backpack,
      solanaAdapterName: SolanaWalletNames.Backpack,
      networks: [WalletAdaptedNetwork.Solana],
      get installed() {
        return isSolanaWalletInstalled(SolanaWalletNames.Backpack) || Boolean((safeGetWindow() as any)?.backpack)
      },
      downloadLink: 'https://backpack.app/',
    },
  ].map(wrapInstalledSafe) as WalletConfigV3[]

  if (walletFilter === WalletFilterValue.SolanaOnly) {
    return wallets.filter((wallet) =>
      wallet.networks.includes(WalletAdaptedNetwork.Solana),
    ) as WalletConfigV3<SolanaConnectorNames>[]
  }

  if (walletFilter === WalletFilterValue.EVMOnly) {
    return wallets.filter((wallet) =>
      wallet.networks.includes(WalletAdaptedNetwork.EVM),
    ) as WalletConfigV3<SolanaConnectorNames>[]
  }

  return wallets as WalletConfigV3[]
}

export const TOP_WALLETS_ID_CONFIG = {
  MultiChain: [WalletIds.Metamask, WalletIds.Trust, WalletIds.BinanceW3W, WalletIds.Okx],
  Evm: [WalletIds.Metamask, WalletIds.Trust, WalletIds.BinanceW3W, WalletIds.Okx],
  Solana: [WalletIds.Phantom, WalletIds.BinanceW3W, WalletIds.Solflare, WalletIds.Backpack],
}

// Chain-specific top wallets configuration
export const CHAIN_TOP_WALLETS_CONFIG: { [chainId: number]: WalletIds[] } = {
  [ChainId.MONAD_MAINNET]: [WalletIds.Metamask, WalletIds.Okx, WalletIds.Walletconnect],
}

export const getTopWalletsConfig = (
  wallets: WalletConfigV3[],
  walletFilter: WalletFilterValue,
  chainId?: number,
): WalletConfigV3[] => {
  // Check for chain-specific config first
  if (chainId && CHAIN_TOP_WALLETS_CONFIG[chainId]) {
    return CHAIN_TOP_WALLETS_CONFIG[chainId]
      .map((id) => wallets.find((wallet) => wallet.id === id))
      .filter(Boolean) as WalletConfigV3[]
  }

  if (walletFilter === WalletFilterValue.SolanaOnly) {
    return TOP_WALLETS_ID_CONFIG.Solana.map((id) => wallets.find((wallet) => wallet.id === id)).filter(
      Boolean,
    ) as WalletConfigV3<SolanaConnectorNames>[]
  }

  if (walletFilter === WalletFilterValue.EVMOnly) {
    return TOP_WALLETS_ID_CONFIG.Evm.map((id) => wallets.find((wallet) => wallet.id === id)).filter(
      Boolean,
    ) as WalletConfigV3<EvmConnectorNames>[]
  }

  return TOP_WALLETS_ID_CONFIG.MultiChain.map((id) => wallets.find((wallet) => wallet.id === id)).filter(
    Boolean,
  ) as WalletConfigV3[]
}
